package com.intel.core 
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	
	/**
	 * Base visual component class that uses a similar approach to Minimal Comps (Bit-101)
	 * for invalidation
	 * 
	 * @author Fintan Boyle
	 */
	public class UIComponent extends Sprite 
	{
		private var appStage:Stage;
		private var appRoot:Sprite;
		public var appWidth:Number;
		public var appHeight:Number;
		
		protected var _width:Number = 0;
		protected var _height:Number = 0;
		
		public function UIComponent(parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number =  0) 
		{
			this.appStage = Application.stage;
			this.appRoot = Application.root;
			this.appWidth = Application.applicationWidth;
			this.appHeight = Application.applicationHeight;
			
			//this.stage.align = StageAlign.TOP_LEFT;
			//this.stage.scaleMode = StageScaleMode.NO_SCALE;
			
			move(xpos, ypos);
			if(parent != null)
			{
				parent.addChild(this);
			}
			
			init();
			
		}
		
		private function init():void
		{
			addChildren();
			invalidate();
		}
		
		/**
		 * Overridden in subclasses to create child display objects.
		 */
		protected function addChildren():void{}
		
		/**
		 * Marks the component to be redrawn on the next frame.
		 * Called every time position or dimension changes 
		 */
		protected function invalidate():void 
		{
			addEventListener(Event.ENTER_FRAME, onInvalidate); 
		}
		
		/**
		 * Called one frame after invalidate is called.
		 */
		protected function onInvalidate(event:Event):void
		{
			removeEventListener(Event.ENTER_FRAME, onInvalidate);
			draw();
		}
		
		/**
		 * Overriden in subclasses to create child display objects.
		 */
		public function draw():void {}
		
		
		/**
		 * Moves the component to the specified position.
		 * @param xpos the x position to move the component
		 * @param ypos the y position to move the component
		 */
		public function move(xpos:Number, ypos:Number):void
		{
			x = Math.round(xpos);
			y = Math.round(ypos);
		}
		
		///////////////////////////////////
		// getter/setters
		///////////////////////////////////
		
		/**
		 * Sets/gets the width of the component.
		 */
		override public function set width(w:Number):void
		{
			_width = w;
			invalidate();
			dispatchEvent(new Event(Event.RESIZE));
		}
		
		override public function get width():Number
		{
			return _width;
		}
		
		/**
		 * Sets/gets the height of the component.
		 */
		override public function set height(h:Number):void
		{
			_height = h;
			invalidate();
			dispatchEvent(new Event(Event.RESIZE));
		}
		override public function get height():Number
		{
			return _height;
		}
		
		/**
		 * Overrides the setter for x to always place the component on a whole pixel.
		 */
		override public function set x(value:Number):void
		{
			super.x = Math.round(value);
		}
		
		/**
		 * Overrides the setter for y to always place the component on a whole pixel.
		 */
		override public function set y(value:Number):void
		{
			super.y = Math.round(value);
		}
		
		/*override public function get root():DisplayObject
		{
			return this.appRoot;
		}*/
		
		public function getAppRoot():Sprite
		{
			return this.appRoot;
		}
		
		override public function get stage():Stage
		{
			return this.appStage;
		}
		
	}
	
}